; disk.asm
; disk drive routines

	.include "files.inc"
	.include "vicrom.inc"
	.include "string.inc"
	.include "memory.inc"
	.include "util.inc"
	
	.export scandrives
	.export dread
	.export drvfirst
	.export drvnext
	.export readrtc
	.export has_rtc

	.segment "DATA"
	
drivecnt:	.byte 0

	iecdrvcnt = 4
	
drives:		.repeat iecdrvcnt
			.byte 0
			.endrep
dridlo:		.repeat iecdrvcnt
			.byte 0
			.endrep
dridhi:		.repeat iecdrvcnt
			.byte 0
			.endrep

rtcread:	.byte 8, 15, 4, "t-rb"
rtcdrvno:	.byte 0
	
	.segment "BOOT"
	
	inbuf_size = 80
	
inbuf:		.byte inbuf_size, 0
			.res inbuf_size
			.byte 0
emptystr:	.byte 8, 15, 0
iecdrives:	.byte 8, 9, 10, 11
actscan:	.byte 0
	
scandrives:	lda #<inbuf			; setup read buffer
			ldx #>inbuf
			jsr ssetbuf
			ldy #0				; drivecnt := 0
			sty drivecnt
@nextdrive:	sty actscan			; save act scan index
			lda iecdrives, y	; get device no
			sta emptystr
			pha
			lda #<emptystr		; read status channel
			ldx #>emptystr
			jsr open
			jsr close
			pla
			bcs @nodrive
			jsr fstatus
			cpx #0
			bne @nodrive
			jsr driveadd		; no error -> drive detected
@nodrive:	ldy actscan			; next index
			iny
			cpy #iecdrvcnt
			bne @nextdrive
			rts

detectstr:	.byte 8, 15, 2, "ui", 0

driveadd:	; A drive no to add
			ldy drivecnt		; no error -> drive detected
			sta drives, y
			sta detectstr
			lda #<detectstr
			ldx #>detectstr
			jsr dread
			bcs @nostr
			jsr sgetlen			; alloc memory for string
			clc					; lenght ++ (len byte)
			adc #1
			ldx #0
			jsr malloc
			ldy drivecnt		; store ptr to drive table
			sta dridlo, y
			pha
			txa
			sta dridhi, y
			tax					; copy string to block
			pla
			jsr scopyto
			lda detectstr		; check for RTC
			sta rtcread
			lda #<rtcread
			ldx #>rtcread
			jsr dread
			bcs @nortc
			jsr sgetlen			; check reply
			cmp #8
			bcc @nortc
			lda inbuf+2
			cmp #7
			bcs @nortc
			lda rtcread			; RTC found, save drive no
			sta rtcdrvno
@nortc:		inc drivecnt
@nostr:		rts

;
;	Boot time RTC read
;	OUTPUT:
;		A .. hour (0..23)
;		X .. minute
;		Y .. second
;		C=0 .. RTC found, time ok
;		C=1 .. no RTC present

readrtc:	lda rtcdrvno
			beq @rrfail
			sta rtcread
			lda #<inbuf			; setup read buffer
			ldx #>inbuf
			jsr ssetbuf
			lda #<rtcread
			ldx #>rtcread
			jsr dread
			bcs @rrfail
			jsr sgetlen			; check reply
			cmp #8
			bcc @rrfail
			lda inbuf+2
			cmp #7
			bcs @rrfail
			lda inbuf+8			; get second
			jsr bcd2bin
			tay
			lda inbuf+7			; get minute
			jsr bcd2bin
			tax
			lda inbuf+6			; get hour
			jsr bcd2bin
			lsr inbuf+9			; check am/pm flag
			bcc @am
			clc
			adc #12				; add 12 for pm
			cmp #24
			bcc @rrok
@toz:		lda #12				; 12pm = 12:00
			clc
@rrok:		rts
@am:		cmp #12				; 12am = 00:00
			bcc @rrok
			lda #0
			clc
			rts
@rrfail:	sec
			rts

	.segment "CODE"

has_rtc:	lda rtcdrvno
			rts

dread:		; A/X .. drive(byte), sec.addr.(byte), open string
			; active string ... buffer
			jsr open
			bcs @err
			pha
			tax
			jsr sclear
			txa
			jsr gets
			pla
			jsr close
@err:		rts

	.segment "DATA"

actdrv:		.byte 0

	.segment "CODE"

drvfirst:	; A .. drive no (0 .. no more drives), X/Y ... ptr to initial status msg
			lda #0
			sta actdrv
drvnext:	lda #0
			ldx actdrv
			cpx drivecnt
			bcs	@end
			lda drives, x
			beq @end
			pha
			lda dridlo, x
			ldy dridhi, x
			tax
			pla
			inc actdrv
@end:		rts

